package com.sjh.lib_app.baseui

//import com.umeng.analytics.MobclickAgent
import android.content.Context
import android.content.pm.ActivityInfo
import android.content.res.Resources
import android.os.Build
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.launcher.ARouter
import com.noober.background.BackgroundLibrary
import com.sjh.lib_app.HintSoftInput
import com.sjh.lib_app.ScreenOrientation
import com.sjh.lib_app.utils.StatusBarUtil
import me.jessyan.autosize.AutoSizeCompat
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe

/**
 * 基础Activity
 *
 * 0. 使用 ARouter 的 Autowired 注解时，已自动添加 ARouter.getInstance().inject(this) 这行代码
 * 1. 使用 EventBus 时，不需要注册与取消注册，baseActivity里面自动判断了，如果有使用EventBus,会自动注册与取消
 * 2. 支持使用 ScreenOrientation 注解指定屏幕方向，如果不指定屏幕方向，默认为竖屏
 * 3. 支持使用 HintSoftInput 注解实现点击空白隐藏软键盘的功能
 *
 * @author Extends
 * @date 2020/6/10
 */
abstract class BaseActivity:AppCompatActivity() {

    /**
     * 是否使用了EvnetBus
     */
    private var hasEvent = false

    /**
     * 是否需要点击空白隐藏软键盘
     */
    private var isHintSoftInput = false

    /**
     * 返回值可以是ResLayout/View/null
     * @return null，那么表示调用者将在onCreatRootView方法里自己调用setContentView方法，否则抛出空指针异常
     */
    protected abstract fun onCreateRootView(): Any?

    protected abstract fun onInitView(savedInstanceState: Bundle?)
    protected abstract fun initListener()
    protected abstract fun initData()

    override fun onCreate(savedInstanceState: Bundle?) {
        // 初始化BackgroundLibrary
        BackgroundLibrary.inject(this)

        // 判断是否使用了EvnetBus
        initEvent()
        // 判断是否需要点击空白隐藏键盘
        initHintSoftInput()
        // 判断是否使用了ARouter的Autowired注解
        initARouter()


        //在设置内容之前的初始化操作
        preInit()

        super.onCreate(savedInstanceState)
        // 初始化屏幕方向
        initScreenOrientation()

        //设置状态栏
//        initStatusBar()
        //设置内容view
        initContentView()

        //配置view的初始化信息
        onInitView(savedInstanceState)

        //初始化监听回调
        initListener()

        //初始化数据
        initData()


        if(hasEvent){
            EventBus.getDefault().register(this)
        }
    }


    /**
     * 在设置内容之前的初始化操作
     */
    open fun preInit(){}

    /**
     * 初始化内容View
     */
    private fun initContentView() {
        val crv = onCreateRootView()
        val contentView = findViewById<ViewGroup>(android.R.id.content)?.getChildAt(0)
        if (crv == null) {
            if (contentView == null) throw NullPointerException(this::class.java.simpleName + "'s contentView is null")
        } else {
            when (crv) {
                is Int -> setContentView(crv)
                is View -> setContentView(crv)
                else -> {
                    if (contentView == null) throw NullPointerException(this::class.java.simpleName + "'s contentView is null")
                }
            }
        }
    }

    /**
     * 初始化屏幕方向
     */
    private fun initScreenOrientation(){
        val screenOrientation = this::class.java.getAnnotation(ScreenOrientation::class.java)
        requestedOrientation = when (screenOrientation?.orientation) {
            -1 -> ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
            0 -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            else -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }
    }

    /**
     * 判断是否需要点击空白隐藏软键盘
     */
    private fun initHintSoftInput(){
        if(this::class.java.getAnnotation(HintSoftInput::class.java) != null){
            isHintSoftInput = true
        }
    }

    /**
     * 判断是否使用了ARouter的Autowired注解
     */
    private fun initARouter(){
        try {
            Class.forName("${javaClass.name}\$\$ARouter\$\$Autowired")
            ARouter.getInstance().inject(this)
        }catch (e:Exception){}
    }

    override fun onDestroy() {
        super.onDestroy()
        if(hasEvent && EventBus.getDefault().isRegistered(this)){
            EventBus.getDefault().unregister(this)
        }
    }

    override fun getResources(): Resources {
        runOnUiThread {
            AutoSizeCompat.autoConvertDensityOfGlobal((super.getResources()))
        }
        return super.getResources()
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (isHintSoftInput && ev.action == MotionEvent.ACTION_DOWN) {
            val v = currentFocus
            if (isShouldHideKeyboard(v, ev)) {
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(v?.windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
            }
        }
        return super.dispatchTouchEvent(ev)
    }

    /**
     * 根据点击位置判断是否应该关闭软键盘
     */
    private fun isShouldHideKeyboard(v: View?, event: MotionEvent): Boolean {
        if (v != null && (v is EditText)) {
            val l = intArrayOf(0, 0)
            v.getLocationInWindow(l)
            val left = l[0]
            val top = l[1]
            val bottom = top + v.getHeight()
            val right = left + v.getWidth()
            return !(event.x > left && event.x < right
                    && event.y > top && event.y < bottom)
        }
        return false
    }

    /**
     * 改变状态栏颜色
     * @param color
     * @param isCilp 是否需要padding状态栏高度，如果需要自己实现状态栏逻辑就传入false
     * @param dl 如果要兼容DrawerLayout则传入
     */
    fun changeStatusBarColor(@ColorInt color: Int, isCilp: Boolean = true, dl: androidx.drawerlayout.widget.DrawerLayout? = null) {
        //如果dl不为空则都使用半透明，因为dl可能拉出白色背景
        if (dl != null) {
            StatusBarUtil.setStatusBarLightMode(this, false)
            StatusBarUtil.setColorTranslucentForDrawerLayout(this, dl, color)
            return
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //如果版本号大于等于M，则必然可以修改状态栏颜色
            StatusBarUtil.setColor(this, color, isCilp)
            StatusBarUtil.setStatusBarLightModeByColor(this, color)
            return
        }
        //这里处理的是版本号低于M的系统
        //判断设置的颜色是深色还是浅色，然后设置statusBar的文字颜色
        val status = StatusBarUtil.setStatusBarLightModeByColor(this, color)
        //fixme 如果手机机型不能改状态栏颜色就不允许开启沉浸式,如果业务需求请修改代码逻辑
        if (!status) {//如果状态栏的文字颜色改变失败了则设置为半透明
            StatusBarUtil.setColorTranslucent(this, color, isCilp)
        } else {//如果状态栏的文字颜色改变成功了则设置为全透明
            StatusBarUtil.setColor(this, color, isCilp)
            //改变了状态栏后需要重新设置一下状态栏文字颜色
            StatusBarUtil.setStatusBarLightModeByColor(this, color)
        }

    }

    /**
     * 判断是否使用了EventBus
     */
    private fun initEvent(){
        hasEvent = hasAnnotationFromMethods(Subscribe::class.java)
    }

    /**
     * 判断方法中是否有指定的注解
     */
    private fun hasAnnotationFromMethods(clazz: Class<out Annotation>):Boolean{
        this::class.java.methods.forEach {
            if(it.isAnnotationPresent(clazz)){
                return true
            }
        }
        return false
    }

    /**
     * 判断属性中是否有指定的注释
     */
    private fun hasAnnotationFromFild(clazz: Class<out Annotation>):Boolean{
        this::class.java.fields.forEach {
            println(it.name)
            if(it.isAnnotationPresent(clazz)){
                return true
            }
        }
        return false
    }

//    override fun onResume() {
//        super.onResume()
//        MobclickAgent.onResume(this@BaseActivity)
//    }
//
//    override fun onPause() {
//        super.onPause()
//        MobclickAgent.onPause(this@BaseActivity)
//    }
}